#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/select.h>
#include <pthread.h>
#include <fcntl.h>
#include <time.h>

#define max(a,b) ((a)>(b)?(a):(b))

int p[3][2],maxrfd;

void *func(void *arg) {
	int id = *((int*)arg);
	printf("id=%d\n", id);
	while (true) {
		char buff[100];
		sprintf(buff, "i am %d\n", id);
		write(p[id][1], buff, strlen(buff));
		sleep(5);
	}

}

int set_no_blocking(int fd) {
	int flags = fcntl(fd, F_GETFL, 0);
	flags |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flags);
	return fd;
}

int main() {
	pipe(p[0]);
	pipe(p[1]);
	pipe(p[2]);
	for (int i = 0; i < 3; i++) {
		set_no_blocking(p[i][0]);
		set_no_blocking(p[i][1]);
	}

	fd_set allrfs, allwfs, readfs, writefs;
	FD_ZERO(&allrfs);
	FD_ZERO(&allwfs);
	
	for (int i = 0; i < 3; i++) {
		FD_SET(p[i][0], &allrfs);
		FD_SET(p[i][1], &allwfs);
	}
	maxrfd = max(p[0][0], max(p[1][0],p[2][0]));
	maxrfd++;

	int arg[3] = {0,1,2};
	pthread_t pthr[3];
	for (int i = 0; i < 3; i++) {
		pthread_create(pthr+i, NULL, func, arg+i);
	}

	while (true) {
		readfs = allrfs;
		int nf = select(maxrfd, &readfs,NULL,NULL,NULL);
		for (int fd = 0; fd < maxrfd; fd++) {
			if (!FD_ISSET(fd, &readfs)) continue;
			int i;
			for (i = 0; i < 3; i++)
				if (fd == p[i][0]) {
					printf("(%d)read ready\n", i);
					char buff[100];
					ssize_t n = read(fd, buff, 100);
					buff[n] = '\n', write(1, buff, n);
					break;
				}
		}
	}

	return 0;
}
